﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace AutoUpgrade
{
    static class Program
    {
        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            if (args.Length == 0 || (args[0] == "start" && args.Length == 3))
            {
                // 复制更新程序，使其独立运行
                Assembly assembly = typeof(Program).Assembly;
                FileInfo fileInfo = new FileInfo(assembly.Location);
                string fileName = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName(), $"{fileInfo.Name}");
                FileInfo destfileInfo = new FileInfo(fileName);
                if (!destfileInfo.Directory.Exists)
                    Directory.CreateDirectory(destfileInfo.Directory.FullName);
                if (File.Exists(fileName))
                    File.Delete(fileName);
                System.IO.File.Copy(fileInfo.FullName, fileName);

                var startInfo = new System.Diagnostics.ProcessStartInfo();
                startInfo.UseShellExecute = true;
                startInfo.WorkingDirectory = Environment.CurrentDirectory;
                startInfo.FileName = fileName;

                string arguments = "run";
                if (args.Length == 3 && args[0] == "start")
                    arguments = $"run {args[1]} {args[2]}";

                //设置启动动作,确保以管理员身份运行
                startInfo.Verb = "runas";
                startInfo.Arguments = arguments;
                System.Diagnostics.Process.Start(startInfo);
            }
            // 运行更新程序
            else if (args.Length > 0 && args[0] == "run")
            {
                if (args.Length == 3)
                {
                    GlobalSetting.Host = args[1];
                    GlobalSetting.StartupApplication = args[2];
                }
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.ThreadException += Application_ThreadException;
                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
                AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
                Application.Run(new UpgradeForm());
            }
            // 打包,生成程序的配置文件
            else if (args.FirstOrDefault(x => x.ToLower() == "init") != null)
            {
                CommandHandle handle = new CommandHandle();
                handle.Init();
            }
            // 打包,生成程序的配置文件
            else if (args.FirstOrDefault(x => x.ToLower() == "pack") != null)
            {
                string path = System.Windows.Forms.Application.StartupPath;
                string description = "自动升级程序";
                if (args.Length >= 2)
                    path = System.IO.Path.GetFullPath(args[1]);
                CommandHandle handle = new CommandHandle();
                handle.Pack(path, description);
            }
            // 打包,生成程序的配置文件
            else if (args.FirstOrDefault(x => x.ToLower() == "-f" || x.ToLower() == "ignore") != null)
            {
                if (args.Length >= 2)
                {
                    CommandHandle handle = new CommandHandle();
                    handle.Ignore(args[1]);
                }
            }
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            MessageBox.Show(e.ExceptionObject.ToString(), "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        static readonly Dictionary<string, Assembly> dynamic_assembly = new Dictionary<string, Assembly>();
        /// <summary>
        /// 在对程序集的解析失败时发生，用于插件的dll与程序集不同位置时，指定路径的程序集
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        private static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            Assembly assembly = default;
            AssemblyName assemblyName = new AssemblyName(args.Name);
            if (dynamic_assembly.ContainsKey(assemblyName.Name))
                assembly = dynamic_assembly[assemblyName.Name];
            else
            {
                switch (assemblyName.Name)
                {
                    case "ICSharpCode.SharpZipLib":
                        assembly = Assembly.Load(Properties.Resources.ICSharpCode_SharpZipLib);
                        break;
                    default:
                        break;
                }
            }
            return assembly;
        }

        private static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {
            MessageBox.Show(e.Exception.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
    }
}
